﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using AzukiMap.DataSource;
using AzukiMap.Map;
using Geotools.Geometries;

namespace AzukiMap.Layer
{
    public class VirtualEarthLayer : TiledLayer
    {
        VirtualEarthTiles _mapSource;

        public VirtualEarthLayer(VirtualEarthTiles tileData, MapCanvas mapCanvas, string name)
            : base(tileData, mapCanvas, name)
        {
            _mapSource = tileData;
        }

        protected override string CreateTileReqString(double tileScale, int pixX, int pixY)
        {
            int level = GetVElevel(tileScale);
            int tileX = pixX / _mapSource.TileWidth;
            int tileY = pixY / _mapSource.TileHeight;
            string tileId = VirtualEarthTileSystem.TileXYToQuadKey(tileX, tileY, level);

            VirtualEarthLayerType lType = _mapSource.TileType;
            string prefix = _mapSource.TilePrefixes[lType];
            string extension = _mapSource.TileExtensions[lType];
            string additions = _mapSource.AdditionalParams[lType];

            return prefix + tileId + extension + additions;
        }

        protected override GTCoordinate GetGeoPointFromTileCoord(int tx, int ty, double tileScale)
        {
            double lon = 0;
            double lat = 0;
            int level = GetVElevel(tileScale); 
            VirtualEarthTileSystem.PixelXYToLatLong(tx, ty, level, out lat, out lon);

            return new GTCoordinate(lon, lat);
        }

        protected override GTCoordinate GetTileOrigin(double lon, double lat, double tileScale)
        {
            int level = GetVElevel(tileScale); 
            int pixX;
            int pixY;
            int originX;
            int originY;
            VirtualEarthTileSystem.LatLongToPixelXY(lat, lon, level, out pixX, out pixY);
            VirtualEarthTileSystem.PixelXYToTileXY(pixX, pixY, out originX, out originY);

            return new GTCoordinate(originX * _mapSource.TileWidth, originY * _mapSource.TileHeight);
        }

        protected override double GetTileScale(double scale)
        {
            double nearestScale = 0;
            for (int i = 0; i < _mapSource.Scales.Count; i++)
            {
                double tileScale = _mapSource.Scales[i];
                if (tileScale > scale)
                {
                    // TODO: find a more better way.
                    nearestScale = _mapSource.Scales[i + 1];
                    break;
                }
            }

            /*
            foreach (double tileScale in _mapSource.Scales)
            {
                if (tileScale > scale)
                {
                    // TODO: find a more better way.
                    nearestScale = tileScale;
                    break;
                }
                nearestScale = tileScale;
            }
             */

            if (nearestScale == 0)
            {
                nearestScale = _mapSource.Scales[0];
            }
            return nearestScale;
        }

        int GetVElevel(double scale)
        {
            return _mapSource.LevelsOfDetail[scale];
        }
    }
}
